﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

namespace QDasTransfer.Classes
{
	public class ParamaterData
	{

		public string filename = Path.GetFullPath("config.xml");

		/// <summary>
		/// 所支持编码格式，0=默认；1=ASCII；2=BigEndiaUnicode；
		/// 3=Unicod；4=UTF32；5=UTF8；6=UTF7。
		/// </summary>
		public static Encoding[] Encodings = {
			Encoding.Default,
			Encoding.ASCII,
			Encoding.BigEndianUnicode,
			Encoding.Unicode,
			Encoding.UTF32,
			Encoding.UTF8,
			Encoding.UTF7};


		/*******************************************************
		 *  Configuration.Input
		 ********************************************************/
		/// <summary>
		/// 有三种处理方式：0=不变；1=移动；2=删除；3=程序处理。
		/// How to process source file: 0.move; 1.no operation. 2. delete. 3. by program.
		/// </summary>
		public int ProcessSourceFileType = 0;

		/// <summary>
		/// 转换成功后的路径，默认为 C:\QDas\Backups\Success。
		/// </summary>
		public string SucceededFolder = @"C:\QDas\Backups\Success";
		/// <summary>
		/// 转换失败后的路径，默认路径为 C:\QDas\Backups\Failed。
		/// </summary>
		public string FailedFolder = @"C:\QDas\Backups\Failed";


		/*******************************************************
		 *  Configuration.Output
		 ********************************************************/
		/// <summary>
		/// 输出文件夹，用于存放转换好的文件。
		/// </summary>
		public String OutputFolder = "C:\\QDas\\Output";
		/// <summary>
		/// 在输出文件时，是否保留原输入文件的路径。
		/// -1=不保存；0=返回所有级数；>1返回指定级数，超出时返回最大级数。
		/// How many levels kept for output folder.
		/// </summary>
		public int KeepOutFolderStructLevel = -1;
		/// <summary>
		/// 临时文件夹，用于保存临时文件。
		/// </summary>
		public String TempFolder = "C:\\QDas\\Temp";
		/// <summary>
		/// 决定如何处理文件名如果已经存在的话。0=覆盖；1=加时间；2=加增量数。
		///  Determine how to deal with files with the same name as the output file. 
		///  0=override;  1=reanme by adding time tick, such as 1_20120516183025.dfq
		///  2=add increased index by 1.
		/// </summary>
		public int ChangeFileNameTypeIfExisted = 0;
		/// <summary>
		/// 向文件尾添加时间缀，时间戳格式为 yyyyMMddHHmmss
		/// </summary>
		public bool AddTimeTickToOutputFile = false;
		/*******************************************************
		*  Configuration.Automate
		********************************************************/
		/// <summary>
		/// 运行程序的次数。
		/// 0=默认，执行一次就结束；-1表示无限制，>0 表示执行指定次数。
		/// </summary>
		public int ExecutionTimes = 0;
		/// <summary>
		/// 执行的周期，格式为 type*10000 + value.
		///  type in [0, 6]: 0=秒；1=分；2=小时；3=天；4=周；5=月；6=年. value in [0,9999].
		///  如 300秒表示为 0*10000+300=300, 6小时表示为 2*10000+6=20006. 15天为30015， etc.
		/// </summary>
		public int AutomaticInterval = 1;
		/*******************************************************
		*  Configuration.Encoding
		********************************************************/
		/// <summary>
		/// 输入编码：0=默认；1=ASCII；2=BigEndiaUnicode；
		/// 3=Unicod；4=UTF32；5=UTF8；6=UTF7。
		/// </summary>
		public int InputEncodingIndex = 0;
		/// <summary>
		/// 输出编码：0=默认；1=ASCII；2=BigEndiaUnicode；
		/// 3=Unicod；4=UTF32；5=UTF8；6=UTF7。
		/// </summary>
		public int OutputEncodingIndex = 0;

		/*******************************************************
		 *  Configuration.Others
		 ********************************************************/ 
		/// <summary>
		/// Show confirming dialog while closing.
		/// </summary>
		public bool ConfirmWhileClosing = true;
		/// <summary>
		/// Immediately start transducing when this program is started.
		/// </summary>
		public bool StartTransducingWhenStartup = false;




		/// <summary>
		/// How to deal with output struct. 0: do not keep structure; 1: keep all structure; otherwise: undefined.
		/// </summary>
		public int KeepOutFolderStructType = 0;

		/// <summary>
		/// How to deal with backup struct. 0: do not keep structure; 1: keep all structure; otherwise: undefined.
		/// </summary>
		public int KeepBackupFolderStructType = 0;
		/// <summary>
		/// How many levels kept for backup folder.
		/// </summary>
		public int KeepBackupFolderStructLevel = 0;
		/// <summary>
		/// Start with windows.
		/// </summary>
		public bool StartWithWindows = false;





		/// <summary>
		/// 打开文件时，选择的默认索引序号同，如“txt文件|*.txt|所有文件|*.*”
		/// 注意：此值下标从1开始，所以默认为1。
		/// </summary>
		public int FilterIndex = 1;
		/// <summary>
		/// 是否显示文件选项，有个别不是根据文件保存的，而是文件组，如COMAU，这样这时就不显示文件选项了。
		/// </summary>
		public bool ShowFileOption = true; 
		/// <summary>
		/// Whether add a time stamp when saving from input file name.
		/// </summary>
		public bool AppendTimeStamp = true;
		/// <summary>
		/// 是否遍历子目录。
		/// </summary>
		public bool TraverseSubfolders = false; 
		/// <summary>
		/// 扩展名列表
		/// </summary>
		public List<string> extentions = new List<string>(); 
		/// <summary>
		/// Supports PDF files.
		/// </summary>
		public bool PdfMode;
		/// <summary>
		/// Output folder.
		/// </summary>
		public string PdfDllFolder;


		/*******************************************************
		 *  User Interface 
		 ********************************************************/
		public List<ListViewData> InputListViewWidth = new List<ListViewData>();




		/*******************************************************
		 *  Input & Output files and folders.
		 ********************************************************/
		public List<string> InputFolders = new List<string>();
		public List<string> InputFiles = new List<string>();
		public List<string> OutputFiles = new List<string>();
		public List<InputPath> InputPaths = new List<InputPath>();


		/******************** Auto Transduce **********************/
		public DateTime StartTime = new DateTime();
		public DateTime EndTime = new DateTime();


		/// <summary>
		/// whether turns on the autotrans. Note: 'SupportAutoTransducer' should be true. 
		/// </summary>
		public bool AutoTransducerAvaliable = false;
		/// <summary>
		/// Whether this transducer supports automatic transduction.
		/// </summary>
		public bool SupportAutoTransducer = false;


		public static ParamaterData Load(string infile)
		{
			if (File.Exists(infile))
			{
				try
				{
					XmlDocument doc = new XmlDocument();
					doc.Load(infile);
					ParamaterData pd = WindGoes6.Data.Serializer.GetObject<ParamaterData>(doc);
					pd.filename = infile;
					return pd;
				}
				catch { }
			}


			return new ParamaterData(infile);
		}

		public ParamaterData()
		{
			Initialize();
		}

		public ParamaterData(string infile)
		{
			filename = infile;
			Initialize();
		}

		public void Initialize()
		{
			string qds = "C:\\QDAS";
			OutputFolder = qds + "\\Output";
			TempFolder = qds + "\\Temp";
			SucceededFolder = qds + "\\Backups\\Success";
			FailedFolder = qds + "\\Backups\\Failed";
			KeepOutFolderStructLevel = 0;
			ProcessSourceFileType = 1;
			ConfirmWhileClosing = true;
			StartTransducingWhenStartup = false;
			StartWithWindows = false;
			StartTime = new DateTime(2000, 1, 1, 0, 0, 0);
			EndTime = new DateTime(2000, 1, 1, 23, 59, 59);
			AutomaticInterval = 1; 
			TraverseSubfolders = false;
			extentions = new List<string>();
		}

		public string GetOutDirectory(string infile)
		{
			return Path.Combine(OutputFolder, FileHelper.GetLastDirectory(infile, KeepOutFolderStructLevel));
		}

		public ParamaterData Clone()
		{
			ParamaterData sp = new ParamaterData();

			for (int i = 0; i < InputFiles.Count; i++)
				sp.InputFiles.Add(InputFiles[i]);

			for (int i = 0; i < InputFolders.Count; i++)
				sp.InputFolders.Add(InputFolders[i]);


			sp.OutputFolder = OutputFolder;
			sp.TempFolder = TempFolder;
			sp.SucceededFolder = SucceededFolder;
			sp.FailedFolder = FailedFolder;

			sp.KeepOutFolderStructType = KeepOutFolderStructType;
			sp.KeepOutFolderStructLevel = KeepOutFolderStructLevel;
			sp.KeepBackupFolderStructType = KeepBackupFolderStructType;
			sp.KeepBackupFolderStructLevel = KeepBackupFolderStructLevel;

			sp.ConfirmWhileClosing = ConfirmWhileClosing;
			sp.StartTransducingWhenStartup = StartTransducingWhenStartup;
			sp.StartWithWindows = StartWithWindows;
			sp.ChangeFileNameTypeIfExisted = ChangeFileNameTypeIfExisted;
			sp.FilterIndex = FilterIndex;
			sp.ShowFileOption = ShowFileOption;
			sp.AppendTimeStamp = AppendTimeStamp;

			sp.AutoTransducerAvaliable = AutoTransducerAvaliable;
			sp.SupportAutoTransducer = SupportAutoTransducer;
			sp.AutomaticInterval = AutomaticInterval;

			sp.StartTime = StartTime;
			sp.EndTime = EndTime;

			return sp;
		}


		public int getCircleInterval()
		{
			return AutomaticInterval;
		}

		/// <summary>
		/// 添加可以被访问的扩展名，名称长度不限，加不加点都行。会自动转换为小写。
		/// </summary>
		/// <param name="name"></param>
		public void AddExt(string name)
		{
			if (string.IsNullOrEmpty(name))
				return;

			if (!name.StartsWith("."))
				name = "." + name;

			extentions.Add(name.ToLower());
		}

		/// <summary>
		/// 验证一个文件全路径是否是合法的文件类型。
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		public bool ValidateExtention(string path)
		{
			string ext = Path.GetExtension(path).ToLower();
			for (int i = 0; i < extentions.Count; i++)
			{
				if (extentions[i].Contains(ext))
				{
					return true;
				}
			}
			return false;
		}

		/// <summary>
		/// 获得可用的扩展名。这个是对话框所使用的。
		/// </summary>
		/// <returns></returns>
		public string GetExtFilter()
		{
			StringBuilder builder = new StringBuilder();

			if (extentions.Count == 0)
				return "所有文件|*.*";

			builder.Append("待转换的数据文件|");
			for (int i = 0; i < extentions.Count; i++)
				builder.Append("*" + extentions[i] + ";");
			builder.Remove(builder.Length - 1, 1);
			builder.Append("|所有文件|*.*");

			return builder.ToString();
		}


		public void Save(string path)
		{
			filename = path;
			Save();
		}

		public void Save()
		{
			if (File.Exists(filename))
				File.Delete(filename);
			WindGoes6.Data.Serializer.GetXmlDoc(this).Save(filename);
		}

		public string GetOutfileName(string infile)
		{
			string keptfolder = FileHelper.GetLastDirectory(infile, KeepOutFolderStructLevel);
			return string.Format("{0}\\{1}.dfq", Path.Combine(OutputFolder, keptfolder), Path.GetFileNameWithoutExtension(infile));
		}
	}
}
